package br.com.sigodonto.model.dao;

import br.com.sigodonto.model.connection.ConnectionManager;
import br.com.sigodonto.model.connection.ConnectionManagerIF;
import java.io.Serializable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.Query;

public class DaoGenerico implements Serializable {

    private EntityManager entityManager;
    private ConnectionManagerIF connectionManagerIF;

    public DaoGenerico() {
        connectionManagerIF = ConnectionManager.getInstance();
        entityManager = connectionManagerIF.getEntityManager();
    }

    public boolean salvar(Object obj){
        entityManager.getTransaction().begin();
        try{
            this.entityManager.persist(obj);
            this.entityManager.getTransaction().commit();
            return true;
        } catch (Exception ex){
            ex.printStackTrace();
            this.entityManager.getTransaction().rollback();
            return false;
        }
    }

    public boolean remover(Object obj){
        entityManager.getTransaction().begin();
        try{
            this.entityManager.remove(obj);
            this.entityManager.getTransaction().commit();
            return true;
        } catch (Exception ex){
            ex.printStackTrace();
            this.entityManager.getTransaction().rollback();
            return false;
        }
    }

    public <T> T atualizar(T t){
        this.entityManager.getTransaction().begin();
        try{
            t = this.entityManager.merge(t);
            this.entityManager.getTransaction().commit();
            return t;
        } catch (Exception ex){
            ex.printStackTrace();
            this.entityManager.getTransaction().rollback();
            return null;
        }
    }

    public <T> T buscar(Class<T> clazz, long key){
        entityManager.getTransaction().begin();
        T objeto = null;
        try{
            objeto = this.entityManager.find(clazz, key);
            this.entityManager.getTransaction().commit();
            return objeto;
        } catch (Exception ex){
            ex.printStackTrace();
            this.entityManager.getTransaction().rollback();
        }
        return objeto;
    }

    public <T> List<T> listarTodos(Class<T> clazz){
        List<T> lista = null;
        entityManager.getTransaction().begin();

        try{
            Query q = entityManager.createQuery("SELECT o FROM "+ clazz.getSimpleName() +" o");
            lista = (List<T>) q.getResultList();
            this.entityManager.getTransaction().commit();
        } catch (Exception ex){
            ex.printStackTrace();
            this.entityManager.getTransaction().rollback();
        }
        return lista;
    }

    public <T> T buscarPorAtributo(Class<T> clazz, String atributo, String valor){
           entityManager.getTransaction().begin();
           T t = null;
           try{
               Query q=entityManager.createQuery("SELECT o FROM "+ clazz.getSimpleName() +" o WHERE o."+atributo+"=:atributo");
               q.setParameter("atributo", valor);
               t = (T) q.getSingleResult();
               this.entityManager.getTransaction().commit();
           } catch (Exception ex){
               ex.printStackTrace();
               this.entityManager.getTransaction().rollback();
           }
           return t;
       }

    public EntityManager getEntityManager() {
        return entityManager;
    }

    public <T> T execultarQueryNomeada(Class<T> clazz, String consulta, Map atributos){
        entityManager.getTransaction().begin();
       T t = null;
       try{
           Query q = entityManager.createQuery(consulta);
           Iterator i = atributos.keySet().iterator();
           while(i.hasNext()){
               String key = (String) i.next();
               q.setParameter(key, atributos.get(key));
           }
           t = (T) q.getSingleResult();
           this.entityManager.getTransaction().commit();
       } catch (Exception ex){
           ex.printStackTrace();
           this.entityManager.getTransaction().rollback();
       }
       return t;
    }
    
    

}
